#ifndef __BUFFER_H
#define __BUFFER_H

#include <cstring>
#include <iostream>
#include <unistd.h>
#include <sys/uio.h>
#include <vector>
#include <atomic>
#include <assert.h>
#include <string>

class Buffer
{
public:
    // 构造函数
    Buffer(int initBuffSize = 1024);
    // 析构函数
    ~Buffer() = default;

    // 返回可写可读以及空闲的字节数
    size_t WritableBytes() const;
    size_t ReadableBtyes() const;
    size_t PrependabelBytes() const;

    // 返回可读数据的起点地址
    const char *Peek() const;
    // 确保有len长度的可写空间
    void EnsureWritable(size_t len);
    // 移动写下标
    void HasWritten(size_t len);

    // 读取len长度的数据
    void Retrieve(size_t len);
    // 读取到end位置
    void RetrieveUntil(const char *end);

    // 取出所有数据，buffer中数据清零，读写下标归零
    void RetrieveAll();
    // 将剩余可读数据读取到str，并清空buffer
    std::string RetrieveAllToStr();

    // 返回可写位置指针，区分权限
    const char *BeginWriteConst() const;
    char *BeginWrite();

    // 重载，从不同地方添加数据到buffer写缓冲区
    void Append(const std::string &str);
    void Append(const char *str, size_t len);
    void Append(const void *data, size_t len);
    void Append(const Buffer &buff);

    // 从fd读数据
    ssize_t ReadFd(int fd, int *Errno);
    // 写数据到fd
    ssize_t WriteFd(int fd, int *Errno);

private:
    // 缓冲区起始地址
    char *BeginPtr_();
    const char *BeginPtr_() const;

    // 扩容空间
    void MakeSpace_(size_t len);

    std::vector<char> buffer_;
    std::atomic<std::size_t> readPos_;
    std::atomic<std::size_t> writePos_;
};

#endif
